<?php

namespace App\Models\Admin;

use App\Models\BaseModel;
use App\Models\Admin\Grade;
use App\Models\Admin\DealRecord;
use App\Models\Admin\TeamAward;
use App\Common\ValidateHandler;
use App\Exports\UsersExport;
use Auth, Excel, Hash;
use DB;

class User extends BaseModel
{
    protected $fillable = [
        'id', 'store_id', 'pid', 'left', 'right', 'level',
        'true_name', 'phone', 'password', 'password_pay', 'weixin', 'grade',
        'nickname', 'avatar', 'open_id', 'union_id', 'gold', 'jf',
        'jgz', 'is_subscribe', 'subscribe_at', 'is_regist', 'regist_at', 'created_at', 'updated_at'
    ];

    public function getList($pageSize, $requestStoreId, $phone, $userId, $grade, $report)
    {
        $storeId = Auth::guard('admin')->user()->store_id;
        $teamAward = new TeamAward;
        $awardName = '订单指数';

        $sql = $this;
        if(!empty($phone)) {
            $sql = $sql->where('phone', 'like', '%'.$phone.'%');
        }
        if(!empty($userId)) {
            $sql = $sql->where('id', $userId);
        }
        if($grade != ''){
            $sql = $sql->where('grade', $grade);
        }
        if ($storeId == 0) {
            // 管理员查看全部店铺会员 按店铺排序
            if ($requestStoreId == 0) {
                $sql = $sql->where('id', '>', 1)->orderBy('store_id', 'asc')->orderBy('created_at', 'desc');
            } else {
                $sql = $sql->where('id', '>', 1)->where('store_id', $requestStoreId)->orderBy('grade', 'desc')->orderBy('created_at', 'desc');
                $team = $teamAward->awardGold($requestStoreId);
                $awardName = $team->award_name;
            }
        } else {
            // 店家只能查看自己店的会员
            $sql = $sql->where('id', '>', 1)->where('store_id', $storeId)->orderBy('created_at', 'desc');
            $team = $teamAward->awardGold($storeId);
            $awardName = $team->award_name;
        }


        if(!empty($report)) {
            $data = $sql->get()->all();
            $data = $this->handleReportData($data);
            return Excel::download(new UsersExport($data,$storeId), 'user.xlsx');
        }

        $data = $sql->paginate($pageSize)->toArray();
        $data = $this->handleData($data);
        $data['awardName'] = $awardName;
        return $this->success($data);
    }

    private function handleReportData($data)
    {   
        $teamIds = array_column($data,'team_id');
        $partners = $this->whereIn('id',$teamIds)->get()->toArray();

        $arr = [];
        foreach ($data as $k => $user) {
            $parent = $this->find($user['pid']);
            $item = [];
            $item['store_id'] = $user['store_id'];
            $item['user_id'] = $user['id'];
            $item['true_name'] = $user['true_name'];
            $item['phone'] = $user['phone'];
            $item['nickname'] = $user['nickname'];
            $item['weixin'] = $user['weixin'];
            $item['pid'] = $user['pid'];
            $item['p_name'] = $parent->nickname;
            $item['partnerId'] = "";
            $item['partner_nickname'] = "";
            foreach ($partners as $key => $value) {
                if($user['team_id'] == $value['id']){
                    $item['partnerId'] = $value['id'];
                    $item['partner_nickname'] = $value['nickname'];
                }
            }
            $item['gold'] = $user['gold'] / 100;
            $item['jf'] = $user['jf']/100;
            $item['jgz'] = $user['jgz'] / 100;
            $item['grade'] = Grade::where('store_id', $user['store_id'])->where('level', $user['grade'])->first()->title;
            $item['level'] = '第' . $user['level']. '代';
            $item['old_user'] = $user['old_user'] ? '是' : '否';
            $item['is_subscribe'] = $user['is_subscribe'] ? '是' : '否';
            $item['partner_at'] = $user['partner_at'];
            $item['created_at'] = $user['created_at'];

            array_push($arr, $item);
        }

        return $arr;
    }

    private function handleData($data)
    {
        foreach ($data['data'] as $k => $user) {
            $data['data'][$k]['gold'] = $data['data'][$k]['gold'] / 100;
            $data['data'][$k]['jf'] = $data['data'][$k]['jf'] / 100;
            $data['data'][$k]['jgz'] = $data['data'][$k]['jgz'] / 100;
            $data['data'][$k]['grade'] = Grade::where('store_id', $data['data'][$k]['store_id'])->where('level', $data['data'][$k]['grade'])->first()->title;

            $parent = $this->where('id', $data['data'][$k]['pid'])->first();
            $data['data'][$k]['p_name'] = $parent->nickname;
            $data['data'][$k]['partnerId'] = "";
            $data['data'][$k]['partner_nickname'] = "";
            if($data['data'][$k]['team_id'] > 0 ){
                $partner = $this->where('id', $data['data'][$k]['team_id'])->first();
                $data['data'][$k]['partnerId'] = $partner->id;
                $data['data'][$k]['partner_nickname'] = $partner->nickname;
            }
        }

        return $data;
    }

    public function handle($id, $data, $type, $handleType, $mark)
    {
        if ($type == 'phone' || $type == 'true_name') {
            $res = $this->setNameOrPhone($id, $data, $type);
            return $res;
        }
        if ($type == 'team_id') {
            $res = $this->upGrade($id, $data);
            return $res;
        }
        if(!($data > 0)) {
            return $this->error(['info' => '请输入大于0的数字']);
        }
        $amount = $data;
        if (!in_array($type, ['gold', 'jf', 'jgz'])) {
            return $this->error(['info' => '操作类型不正确']);
        }
        if ($type == 'gold' || $type == 'jgz') {
            $data = $data * 100;
        }
        $user = $this->where('id', $id)->first();
        $teamAward = new TeamAward;
        $team = $teamAward->awardGold($user->store_id);
        if ($handleType == 'reduce') {
            if ($user->gold < $data && $type == 'gold') {
                return $this->error(['info' => '余额不能为负数']);
            }
            if ($user->jf < $data && $type == 'jf') {
                return $this->error(['info' => '积分不能为负数']);
            }
            if ($user->jgz < $data && $type == 'jgz') {
                return $this->error(['info' => $team->award_name.'不能为负数']);
            }
            $balance = $user->$type - $data;
        } else {
            $balance = $user->$type + $data;
        }

        $this->addRecord($user, $type, $handleType, $data, $balance, $amount, $team->award_name, $mark);
        $user->$type = $balance;
        $user->save();
        return $this->success(['info' => '操作成功']);
    }

    private function addRecord($user, $type, $handleType, $data, $balance, $amount, $awardName, $mark)
    {
        $insertData = [];
        $insertData['store_id'] = $user->store_id;
        $insertData['user_id'] = $user->id;
        $insertData['amount'] = $data;
        $insertData['type'] = $type === 'reduce' ? 'out' : 'in';
        $insertData['status'] = 3;
        $reason = $handleType === 'reduce' ? '扣除' : '充值';
        $handle = '';
        $jmType = 0;
        switch ($type) {
            case 'gold':
                $handle = '余额';
                $jmType = 1;
                break;
            case 'jf':
                $handle = '积分';
                $jmType = 2;
                break;
            case 'jgz':
                $handle = $awardName;
                $jmType = 3;
                break;
        }
        $insertData['reason'] = "管理员$reason".$handle.$amount;
        $insertData['deal_type'] = 3;
        $insertData['last_balance'] = $user->$type;
        $insertData['new_balance'] = $balance;
        $insertData['order_type'] = 4;
        $insertData['jm_type'] = $jmType;
        $insertData['grade'] = $user->grade;
        $insertData['mark'] = empty($mark) ? '' : $mark;

        $dealRecord = new DealRecord;
        $dealRecord->create($insertData);
    }

    private function setNameOrPhone($id, $data, $type)
    {
        $user = $this->where('id', $id)->first();
        $result = $this->validateNameOrPhone($type, $data);
        if (!$result['res']) {
            return $this->error($result);
        }

        if ($type == 'phone') {
            // 手机号排重
            $s = $this->where('phone', $data)->where('store_id', $user->store_id)->exists();
            if ($s) {
                return $this->error(['info' => '此手机号已经存在']);
            }
        }
        $user->$type = $data;
        $user->save();
        return $this->success(['info' => '操作成功']);
    }

    private function validateNameOrPhone($type, $data)
    {
        $arr = [];
        if ($type == 'true_name') {
            $arr[0] = [
                'name' => '姓名',
                'value' => $data,
                'func' => 'is_empty'
            ];
        } else {
            $arr[0] = [
                'name' => '手机号',
                'value' => $data,
                'func' => 'is_phone'
            ];
        }
        return ValidateHandler::do($arr);
    }

    public function getTree($requestStoreId, $userId)
    {
        $storeId = Auth::guard('admin')->user()->store_id;
        $first = $this->where('id', $userId)->first();
        if(empty($first)) {
            return $this->error(['info' => '输入用户不存在']);
        }
        if ($storeId == 0) {
            $data = $this->where('left', '>', $first->left)->where('right', '<', $first->right)->where('store_id', $requestStoreId)->orderBy('level', 'asc')->get()->toArray();
        } else {
            $data = $this->where('left', '>', $first->left)->where('right', '<', $first->right)->where('store_id', $storeId)->orderBy('level', 'asc')->get()->toArray();
        }
        $data = key_val($data);
        $keys = array_keys($data);
        $id = $first->id;
        $data = $this->handleTreeData($data, $id == 1? 0 : $id);

        return $this->success(['nodes' => $data, 'keys' => $keys]);
    }

    private function handleTreeData($data, $pid=0)
    {
        $arr = [];
        if ($pid == 0) {
            $arr[0] = [
                'id' => 1, 
                'label' => '会员关系树',
                'children' => $this->handleTreeData($data, 1)
            ];
        }

        foreach ($data as $key => $value) {
            if ($pid == $value['pid']) {
                $title = Grade::where('store_id', $value['store_id'])->where('level', $value['grade'])->first()->title;
                $item = [
                    'id' => $key, 
                    'label' => $value['nickname'].'--'.$title.'--'.$key,
                    'children' => $this->handleTreeData($data, $value['id'])
                ];
                array_push($arr, $item);
            } else {
                continue;
            }
        }

        return $arr;
    }

    private function upGrade($id, $data)
    {
        $user = $this->where('id', $id)->first();
        $password = Auth::guard('admin')->user()->password;
        if (!Hash::check($data, $password)) {
            return $this->error(['info' => '后台账号密码不正确']);
        }

        //查看推荐链上面是否存在报单中心
        $recom = $this->where('left', '<', $user->left)->where('right', '>', $user->right)->where('store_id', $user->store_id)->orderBy('level','desc')->where('is_partner',1)->first();
        //推荐报单中心ID
        $recom_id = 0;
        if(!empty($recom)){
            $recom_id = $recom->id;
        }

        $grade = new Grade;
        $info =$grade->where('store_id',$user->store_id)->orderBy('level','desc')->first();
        DB::beginTransaction();
        try {
            //当前帐号信息更新 升级为报单中心
            $user->grade = $info->level;
            $user->team_id = $user->id;
            $user->recom_id = $recom_id;
            $user->is_partner = 1;
            $user->partner_at = date("Y-m-d H:i:s");
            $user->save();

            //查看推荐链下面是否存在报单中心
            $partner = $this->where('left', '>', $user->left)->where('right', '<', $user->right)->where('store_id', $user->store_id)->where('is_partner',1)->orderBy('level','asc')->first();
            $result = true;
            if(empty($partner)){
                //推荐链下没有报单中心   
                $data = $this->where('left', '>', $user->left)->where('right', '<', $user->right)->where('store_id', $user->store_id)->update(['team_id'=>$user->id,'recom_id'=>$recom_id]);
            }else{
                //推荐链下存在报单中心   
                //当前团队下的会员 团队标记及推荐报单中心标记更新
                $data = $this->where('left', '>', $user->left)->where('right', '<', $user->right)->where('store_id', $user->store_id)->where('team_id',$recom_id)->update(['team_id'=>$user->id,'recom_id'=>$recom_id]);
                //下面的报单中心团队(下面的报单中心及他们的团队会员) 推荐报单中心标识更新
                $result = $this->where('left', '>', $user->left)->where('right', '<', $user->right)->where('store_id', $user->store_id)->where('recom_id',$recom_id)->where('team_id','!=',$user->id)->update(['recom_id'=>$user->id]);
            }
            if($result){
                DB::commit();
                return $this->success(['info' => '操作成功']);
            }
            return $this->success(['info' => '已经是报单中心了,无需重复操作!']);
        } catch (\Exception $e) {
            DB::rollBack();
            return $e->getLine().$e->getMessage();
        }
    }
}
